
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <locale.h>
#include <inttypes.h>
#include <amanita/aMath.h>
#include <amanita/aVector.h>
#include <amanita/sqlite/aSQLite.h>
#include "Main.h"
#include "occult/Occult.h"
#include "ProfileDlg.h"
#include "astro/Horoscope.h"
#include "astro/HoroscopeChartPage.h"
#include "Profile.h"



enum {
	CATLIST_NAME,
	CATLIST_COLS
};

enum {
	PROFILELIST_NAME,
	PROFILELIST_COLS
};


gboolean ProfileDlg::delete_event_callback(GtkWidget *widget,GtkWidget *event,gpointer data) {
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->hide();
	return TRUE;
}

void ProfileDlg::catlist_selection_changed_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::catlist_selection_changed_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	GtkTreeModel *model;
	GtkTreeIter   iter;

	if(gtk_tree_selection_get_selected(GTK_TREE_SELECTION(widget),&model,&iter)) {
		category *c;
		gtk_tree_model_get(model,&iter,CATLIST_COLS,&c,-1);
		if(c) dlg->loadProfiles(c);
	}
}

void ProfileDlg::profilelist_selection_changed_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::profilelist_selection_changed_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	GtkTreeModel *model;
	GtkTreeIter   iter;

	if(gtk_tree_selection_get_selected(GTK_TREE_SELECTION(widget),&model,&iter)) {
		uint64_t id;
		gtk_tree_model_get(model,&iter,CATLIST_COLS,&id,-1);
		if(id) dlg->loadProfile(id);
	}
}


void ProfileDlg::ok_clicked_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::ok_clicked_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->openBirthChart(dlg->profileid);
}

void ProfileDlg::save_clicked_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::save_clicked_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->saveProfile(dlg->profileid);
}

void ProfileDlg::savenew_clicked_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::savenew_clicked_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->saveProfile(0);
}

void ProfileDlg::cancel_clicked_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::cancel_clicked_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->clearForm();
	dlg->hide();
}

void ProfileDlg::clear_clicked_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::clear_clicked_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->clearForm();
}

void ProfileDlg::delete_clicked_callback(GtkWidget *widget,gpointer data) {
app.printf("ProfileDlg::delete_clicked_callback()");
	ProfileDlg *dlg = (ProfileDlg *)data;
	dlg->deleteProfile(dlg->profileid);
}


void ProfileDlg::createNatalHoroscope(Profile *p) {
	/*if(!p) {
		time_t t = time(0);
		struct tm *now = localtime(&t);
		present->setDate(1900+now->tm_year,now->tm_mon+1,now->tm_mday,
			now->tm_hour,now->tm_min,now->tm_sec,now->tm_isdst>0);
		p = present;
	}*/
	Horoscope *h = new Horoscope(p);
	h->castNatalChart();
	new HoroscopeChartPage(h);
}

/*
void ProfileDlg::createRelationHoroscope(int n1,int n2,int st) {
fprintf(out,"ProfileDlg::createRelationHoroscope(n1=%d,n2=%d,st=%d)\n",n1,n2,st);
fflush(out);
	int n = Window::windows();
	if(n<2) return;
	if(n1<0 || n1>=n) n1 = n-2;
	if(n2<0 || n2>=n) n2 = n-1;
fprintf(out,"ProfileDlg::createRelationHoroscope(n1=%d,n2=%d)\n",n1,n2);
fflush(out);
	AstrologyMDI *a1 = (AstrologyMDI *)Window::getWindow(n1),*a2 = (AstrologyMDI *)Window::getWindow(n2);
	if(!a1 || !a2) return;
	Horoscope *h1 = a1->horoscope,*h2 = a2->horoscope;
fprintf(out,"ProfileDlg::createRelationHoroscope(1)\n");
fflush(out);
	Horoscope *h3 = new Horoscope(h1,h2,st);
fprintf(out,"ProfileDlg::createRelationHoroscope(2)\n");
fflush(out);
	new AstrologyMDI(h3);
fprintf(out,"ProfileDlg::createRelationHoroscope(3)\n");
fflush(out);
}

void ProfileDlg::setHoroscopeStyle(int st) {
	if(!Window::windows()) return;
	HWND hwnd = GetWindow(hmdi,GW_CHILD);
	if(!hwnd) return;
	Window *w = Window::getWindow(GetWindowContextHelpId(hwnd));
	if(!w || w->instance()!=OBJECT_MDI_ASTROLOGY) return;
	AstrologyMDI *a = (AstrologyMDI *)w;
	Horoscope &h = *a->horoscope;
	if(st==h.style || (st&0x300)!=(h.style&0x300)) return;
	h.style = st;
	InvalidateRect(hwnd,0,false);
	UpdateWindow(hwnd);
}
*/

ProfileDlg::ProfileDlg(GtkWindow *parent) : ncats(0),cats(0),profileid(0) {
	const int hpad1 = 4;
	const int vpad1 = 2;
	int i,j,row;
	char str[64];

	GtkWidget *table1,*table2;
	GtkWidget *scroll;
	GtkWidget *widget;
	GtkWidget *hbox;
	GtkTreeSelection *selection;
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *column;
	GtkListStore *store;
	GtkTreeIter iter;

	loadCategories();
	profileid = 0;

	gtk.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(gtk.window),app.get("title.profiledlg"));
	gtk_window_set_transient_for(GTK_WINDOW(gtk.window),parent);
	gtk_window_set_resizable(GTK_WINDOW(gtk.window),FALSE);
	gtk_window_set_position(GTK_WINDOW(gtk.window),GTK_WIN_POS_CENTER);
	//gtk_window_set_icon(GTK_WINDOW(gtk.window),app.createPixbuf(IMAGES_PATH "icons/icon16.png"));
	gtk_container_set_border_width(GTK_CONTAINER(gtk.window),2);
	g_signal_connect(G_OBJECT(gtk.window),"delete_event",G_CALLBACK(delete_event_callback),this);

	table1 = gtk_table_new(3,2,FALSE);
	{
		table2 = gtk_table_new(2,10,FALSE);
		{
			row = 0;
			widget = gtk_label_new(app.get("name"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			gtk.name = gtk_entry_new();
			gtk_table_attach(GTK_TABLE(table2),gtk.name,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);

			++row;
			widget = gtk_hseparator_new();
			gtk_table_attach(GTK_TABLE(table2),widget,0,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("date"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			hbox = gtk_hbox_new(FALSE,5);
			gtk.year = gtk_entry_new();
			gtk_widget_set_size_request(gtk.year,60,-1);
			gtk_box_pack_start(GTK_BOX(hbox),gtk.year,FALSE,FALSE,0);
			gtk.month = gtk_combo_box_text_new();
			for(i=1; i<=12; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.month),(gchar *)app.occult.month(i));
			gtk_box_pack_start(GTK_BOX(hbox),gtk.month,FALSE,FALSE,0);
			gtk.day = gtk_combo_box_text_new();
			for(i=1; i<=31; i++) { sprintf(str,"%02d",i);gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.day),(gchar *)str); }
			gtk_box_pack_start(GTK_BOX(hbox),gtk.day,FALSE,FALSE,0);
			gtk_table_attach(GTK_TABLE(table2),hbox,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("time"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			hbox = gtk_hbox_new(FALSE,5);
			gtk.hour = gtk_combo_box_text_new();
			for(i=0; i<24; i++) { sprintf(str,"%02d",i);gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.hour),(gchar *)str); }
			gtk_box_pack_start(GTK_BOX(hbox),gtk.hour,FALSE,FALSE,0);
			gtk.minute = gtk_combo_box_text_new();
			for(i=0; i<60; i++) { sprintf(str,"%02d",i);gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.minute),(gchar *)str); }
			gtk_box_pack_start(GTK_BOX(hbox),gtk.minute,FALSE,FALSE,0);
			gtk.second = gtk_combo_box_text_new();
			for(i=0; i<60; i++) { sprintf(str,"%02d",i);gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.second),(gchar *)str); }
			gtk_box_pack_start(GTK_BOX(hbox),gtk.second,FALSE,FALSE,0);
			gtk_table_attach(GTK_TABLE(table2),hbox,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			widget = gtk_hseparator_new();
			gtk_table_attach(GTK_TABLE(table2),widget,0,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("country"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			gtk.country = gtk_combo_box_text_new();
			{
				aSQLite sql(app.getLanguageDir(),"location");
				aRecord *r;
				aResultset rs;
				sql.query(rs,"select code,name from country order by name;");
				ncountries = rs.rows();
				countries = (char *)malloc(ncountries*2);
				for(size_t i=0; i<ncountries; i++) {
					r = rs.getRow(i);
					memcpy(&countries[i*2],r->getString(0),2);
					gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.country),(gchar *)r->getString(1));
				}
			}
			gtk_table_attach(GTK_TABLE(table2),gtk.country,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("location"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			gtk.location = gtk_entry_new();
			gtk_table_attach(GTK_TABLE(table2),gtk.location,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			gtk.location2 = gtk_label_new("");
			gtk_misc_set_alignment(GTK_MISC(gtk.location2),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),gtk.location2,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("longitude"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			gtk.longitude = gtk_label_new("");
			gtk_misc_set_alignment(GTK_MISC(gtk.longitude),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),gtk.longitude,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("latitude"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			gtk.latitude = gtk_label_new("");
			gtk_misc_set_alignment(GTK_MISC(gtk.latitude),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),gtk.latitude,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);

			++row;
			widget = gtk_label_new(app.get("timezone"));
			gtk_misc_set_alignment(GTK_MISC(widget),0,0.5);
			gtk_table_attach(GTK_TABLE(table2),widget,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
			gtk.timezone = gtk_combo_box_text_new();
			{
				aSQLite sql(app.getLanguageDir(),"location");
				float gmt;
				aRecord *r;
				aResultset rs;
				sql.query(rs,"select gmt,locale,name from timezone order by gmt,name;");
				ntimezones = rs.rows();
				timezones = (char *)malloc(ntimezones*32);
				tzgmt = (float *)malloc(ntimezones*sizeof(float));
				timezonesgmtindex = -1;
				for(size_t i=0; i<ntimezones; i++) {
					r = rs.getRow(i);
					gmt = r->getFloat(0);
					strcpy(&timezones[i*32],r->getString(1));
					tzgmt[i] = gmt;
					if(!strcmp(r->getString(1),"GMT")) timezonesgmtindex = i;
					sprintf(str,"[%+.02f] %s",gmt,r->getString(2));
					gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk.timezone),(gchar *)str);
				}
			}
			gtk_table_attach(GTK_TABLE(table2),gtk.timezone,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			gtk.dst = gtk_check_button_new_with_label(app.get("dst"));
			gtk_table_attach(GTK_TABLE(table2),gtk.dst,1,2,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);
		}
		gtk_table_attach(GTK_TABLE(table1),table2,0,1,0,1,
			(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
	}

	widget = gtk_vseparator_new();
	gtk_table_attach(GTK_TABLE(table1),widget,1,2,0,1,
		(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);

	{
		table2 = gtk_table_new(1,2,FALSE);
		{
			row = 0;
			scroll = gtk_scrolled_window_new(NULL,NULL);
			gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
			gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll),GTK_SHADOW_IN);
			gtk.catlist = gtk_tree_view_new();
			renderer = gtk_cell_renderer_text_new();
			column = gtk_tree_view_column_new_with_attributes(app.get("categories"),renderer,"text",CATLIST_NAME,NULL);
			gtk_tree_view_append_column(GTK_TREE_VIEW(gtk.catlist),column);
			store = gtk_list_store_new(CATLIST_COLS+1,G_TYPE_STRING,G_TYPE_POINTER);
			category *c = &cats[0];
			for(size_t i=0; c && i<ncats; i++) {
				*str = '\0';
				for(j=0; j<c->lvl; j++) strcat(str,"--> ");
				strcat(str,c->name);
app.printf("ProfileDlg::init(category: index=%d,code='%s',parent='%s',child='%s',category='%s')",c->index,c->code,c->parent? c->parent->code : "",c->child? c->child->code : "",str);
				gtk_list_store_append(store,&iter);
				gtk_list_store_set(store,&iter,CATLIST_NAME,str,CATLIST_COLS,(gpointer)c,-1);
				if(i==ncats-1) break;
				if(c->child) c = c->child;
				else if(cats[c->index+1].parent==c->parent) c = &cats[c->index+1];
				else if(c->parent) {
					for(c=c->parent; c && cats[c->index+1].parent!=c->parent; c=c->parent);
					if(!c->parent && cats[c->index+1].parent) break;
					c = &cats[c->index+1];
				} else break;
			}
			gtk_tree_view_set_model(GTK_TREE_VIEW(gtk.catlist),GTK_TREE_MODEL(store));
			g_object_unref(store);
			gtk_widget_set_size_request(gtk.catlist,200,100);
			selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk.catlist));
			g_signal_connect(selection,"changed",G_CALLBACK(catlist_selection_changed_callback),this);
			gtk_container_add(GTK_CONTAINER(scroll),gtk.catlist);
			gtk_table_attach(GTK_TABLE(table2),scroll,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);

			++row;
			scroll = gtk_scrolled_window_new(NULL,NULL);
			gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
			gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll),GTK_SHADOW_IN);
			gtk.profilelist = gtk_tree_view_new();
			renderer = gtk_cell_renderer_text_new();
			column = gtk_tree_view_column_new_with_attributes(app.get("profiles"),renderer,"text",PROFILELIST_NAME,NULL);
			gtk_tree_view_append_column(GTK_TREE_VIEW(gtk.profilelist),column);
			store = gtk_list_store_new(PROFILELIST_COLS+1,G_TYPE_STRING,G_TYPE_INT);
			gtk_tree_view_set_model(GTK_TREE_VIEW(gtk.profilelist),GTK_TREE_MODEL(store));
			g_object_unref(store);
			gtk_widget_set_size_request(gtk.profilelist,200,-1);
			selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk.profilelist));
			g_signal_connect(selection,"changed",G_CALLBACK(profilelist_selection_changed_callback),this);
			gtk_container_add(GTK_CONTAINER(scroll),gtk.profilelist);
			gtk_table_attach(GTK_TABLE(table2),scroll,0,1,row,row+1,
				(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),hpad1,vpad1);
		}
		gtk_table_attach(GTK_TABLE(table1),table2,2,3,0,1,
			(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),hpad1,vpad1);
	}

	{
		hbox = gtk_hbox_new(FALSE,2);
		{
			widget = gtk_button_new_with_label(app.get("ok"));
			g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(ok_clicked_callback),this);
			gtk_widget_set_size_request(widget,80,-1);
			gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,2);
			widget = gtk_button_new_with_label(app.get("save"));
			g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(save_clicked_callback),this);
			gtk_widget_set_size_request(widget,80,-1);
			gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,2);
			widget = gtk_button_new_with_label(app.get("savenew"));
			g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(savenew_clicked_callback),this);
			gtk_widget_set_size_request(widget,80,-1);
			gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,2);
			widget = gtk_button_new_with_label(app.get("cancel"));
			g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(cancel_clicked_callback),this);
			gtk_widget_set_size_request(widget,80,-1);
			gtk_box_pack_start(GTK_BOX(hbox),widget,FALSE,FALSE,2);
			widget = gtk_button_new_with_label(app.get("delete"));
			g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(delete_clicked_callback),this);
			gtk_widget_set_size_request(widget,80,-1);
			gtk_box_pack_end(GTK_BOX(hbox),widget,FALSE,FALSE,2);
			widget = gtk_button_new_with_label(app.get("clear"));
			g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(clear_clicked_callback),this);
			gtk_widget_set_size_request(widget,80,-1);
			gtk_box_pack_end(GTK_BOX(hbox),widget,FALSE,FALSE,2);
		}
		gtk_table_attach(GTK_TABLE(table1),hbox,0,3,1,2,
			(GtkAttachOptions)(GTK_FILL|GTK_EXPAND),(GtkAttachOptions)(GTK_FILL|GTK_SHRINK),5,5);
	}
	gtk_widget_show_all(table1);
	gtk_container_add(GTK_CONTAINER(gtk.window),table1);
	clearForm();
}


ProfileDlg::~ProfileDlg() {
app.printf("ProfileDlg::~ProfileDlg()");
	if(cats) { free(cats);ncats = 0,cats = 0; }
	if(countries) { free(countries);ncountries = 0,countries = 0; }
	if(timezones) { free(timezones);ntimezones = 0,timezones = 0; }
	gtk_widget_destroy(gtk.window);
}

void ProfileDlg::show() {
	gtk_widget_show(gtk.window);
	
}

void ProfileDlg::hide() {
	gtk_widget_hide(gtk.window);
}

void ProfileDlg::loadCategories() {
	if(cats) free(cats);
	ncats = 0,cats = 0;

	aSQLite sql(app.getLanguageDir(),"profile_category");
	aResultset rs;
	sql.query(rs,"select code,parent,name from category order by parent,number,name;");
	if(!rs.rows()) return;

	size_t i,j;
	char p[5]/*,str[64]*/;
	aRecord *r;
	category *c,*cp;

	ncats = rs.rows();
	cats = (category *)malloc(ncats*sizeof(category));
	memset(cats,0,ncats*sizeof(category));
	for(i=0; i<ncats; i++) {
		r = rs.getRow(i);
app.printf("ProfileDlg::loadCategories(record: index=%d,code='%s',parent='%s',name='%s')",i,r->getString(0),r->getString(1),r->getString(2));
		c = &cats[i];
		c->index = i;
		strncpy(c->code,r->getString(0),5);
		strcpy(c->name,r->getString(2));
		c->lvl = 0;
		if(r->getString(1)) {
			strcpy(p,r->getString(1));
			for(j=0; j<i; j++) if(*cats[j].code==*p && !strncmp(&cats[j].code[1],&p[1],3)) {
				c->parent = &cats[j];
				if(!cats[j].child) cats[j].child = c;
				break;
			}
		}
	}

	for(i=0; i<ncats; i++) {
		c = &cats[i];
		if(c->parent) for(cp=c->parent,c->lvl=0; cp; cp=cp->parent) c->lvl++;
	}
}

ProfileDlg::category *ProfileDlg::getCategory() {
app.printf("ProfileDlg::getCategory(1)");
	GtkTreeSelection *selection;
	GtkTreeModel *model;
	GtkTreeIter iter;

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk.catlist));
app.printf("ProfileDlg::getCategory(2)");
	if(gtk_tree_selection_get_selected(selection,&model,&iter)) {
app.printf("ProfileDlg::getCategory(3)");
		category *c = 0;
		gtk_tree_model_get(model,&iter,CATLIST_COLS,&c,-1);
app.printf("ProfileDlg::getCategory(4)");
		return c;
	}
app.printf("ProfileDlg::getCategory(5)");
	return 0;
}


void ProfileDlg::loadProfiles(category *c) {
	if(!c) c = getCategory();

	GtkListStore *store;
	GtkTreeIter iter;

	store = gtk_list_store_new(PROFILELIST_COLS+1,G_TYPE_STRING,G_TYPE_UINT64);

	aRecord *r;
	aResultset rs;
	aSQLite sql(app.getHomeDir(),"profile");
	sql.queryf(rs,"select id,name from profile where like('_%%%s_%%',category) order by name;",c->code);
	for(size_t i=0; i<rs.rows(); i++) {
		r = rs.getRow(i);
		app.printf("ProfileDlg::loadProfiles(name='%s')",r->getString(1));
		gtk_list_store_append(store,&iter);
		gtk_list_store_set(store,&iter,PROFILELIST_NAME,r->getString(1),PROFILELIST_COLS,(guint64)r->getLongLong(0),-1);
	}
	gtk_tree_view_set_model(GTK_TREE_VIEW(gtk.profilelist),GTK_TREE_MODEL(store));
	g_object_unref(store);
}

void ProfileDlg::setCategory(const char *code) {
	size_t i = 0;
	if(code) {
		for(; i<ncats; i++) if(*code==*cats[i].code && !strncmp(&code[1],&cats[i].code[1],3)) break;
		if(i==ncats) return;
	}
}

void ProfileDlg::loadProfile(uint64_t id) {
	Profile p;
	p.load(id);
	setProfile(p);
}

void ProfileDlg::setProfile(Profile &p) {
	size_t i;
	char lon[18],lat[18],str[64];

	profileid = p.getID();

	gtk_entry_set_text(GTK_ENTRY(gtk.name),p.name());
	sprintf(str,"%d",p.year());
	gtk_entry_set_text(GTK_ENTRY(gtk.year),str);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.month),p.month()-1);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.day),p.day());
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.hour),p.hour());
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.minute),p.minute());
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.second),p.second());

	strcpy(longitude,p.longitude());
	p.printLongitude(lon,app.get("londirs"));
	gtk_label_set_text(GTK_LABEL(gtk.longitude),lon);
	strcpy(latitude,p.latitude());
	p.printLatitude(lat,app.get("latdirs"));
	gtk_label_set_text(GTK_LABEL(gtk.latitude),lat);
	{
		aResultset rs;
		aSQLite sql(app.getLanguageDir(),"location");
		sql.queryf(rs,"select l.name,c.code,c.name from location as l left join country as c on c.code=l.country "
			"where l.longitude='%s' and l.latitude='%s';",p.longitude(),p.latitude());
		if(rs.rows()) {
			aRecord *r = rs.getRow(0);
			char c[2];
			memcpy(c,r->getString(1),2);
			for(i=0; i<ncountries; i++) if(*c==countries[i*2] && c[1]==countries[i*2+1]) break;
			gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.country),i);
			gtk_entry_set_text(GTK_ENTRY(gtk.location),r->getString(0));
			sprintf(str,"%s [%s]",r->getString(0),r->getString(1));
			gtk_label_set_text(GTK_LABEL(gtk.location2),str);
		} else {
			gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.country),-1);
			gtk_entry_set_text(GTK_ENTRY(gtk.location),"");
			gtk_label_set_text(GTK_LABEL(gtk.location2),"");
		}
	}
	{
		const char *tz = p.timezone();
app.printf("Profile[%s], timezone=%s, ntimezones=%d",p.name(),tz,ntimezones);
		for(i=0; i<ntimezones; i++) if(*tz==timezones[i*32] && !strcmp(&tz[1],&timezones[i*32+1])) break;
		gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.timezone),i);
	}
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk.dst),p.dst());
}

void ProfileDlg::getProfile(Profile &p) {
app.printf("ProfileDlg::getProfile(1)");
	category *c = getCategory();
	if(!c) return;

	char cat[512],location[64];

app.printf("ProfileDlg::getProfile(2)");
	p.setName(gtk_entry_get_text(GTK_ENTRY(gtk.name)));
	sprintf(cat," %s ",c->code);
	p.setCategory(cat);

app.printf("ProfileDlg::getProfile(3)");
	int year = atoi(gtk_entry_get_text(GTK_ENTRY(gtk.year)));
	int month = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk.month))+1;
	int day = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk.day));
	int hour = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk.hour));
	int minute = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk.minute));
	int second = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk.second));
	bool dst = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk.dst));
app.printf("ProfileDlg::getProfile(4)");
	p.setDate(year,month,day,hour,minute,second,dst);

app.printf("ProfileDlg::getProfile(5)");
	strcpy(location,gtk_entry_get_text(GTK_ENTRY(gtk.location)));
	int tz = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk.timezone));
	p.setLocation(&timezones[tz*32],tzgmt[tz],longitude,latitude,location,0);//"VÖNS");
app.printf("ProfileDlg::getProfile(6)");
}


void ProfileDlg::openBirthChart(uint64_t id) {
	Profile p;
	p.setID(id);
	getProfile(p);
	p.save();
	profileid = p.getID();

	hide();
	/*if(eventFunction) eventFunction(eventObject,&p);
	else */createNatalHoroscope(&p);
}

void ProfileDlg::clearForm() {
	const char *blank = "";
	char str[32];
	time_t t = time(0);
	struct tm *now = localtime(&t);

	profileid = 0;
	*longitude = '\0';
	*latitude = '\0';
	gtk_entry_set_text(GTK_ENTRY(gtk.name),blank);
	sprintf(str,"%d",1900+now->tm_year);
	gtk_entry_set_text(GTK_ENTRY(gtk.year),str);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.month),now->tm_mon);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.day),now->tm_mday);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.hour),now->tm_hour);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.minute),now->tm_min);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.second),now->tm_sec);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.country),-1);
	gtk_entry_set_text(GTK_ENTRY(gtk.location),blank);
	gtk_label_set_text(GTK_LABEL(gtk.location2),blank);
	gtk_label_set_text(GTK_LABEL(gtk.longitude),blank);
	gtk_label_set_text(GTK_LABEL(gtk.latitude),blank);
	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk.timezone),timezonesgmtindex);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk.dst),now->tm_isdst>0);
}

void ProfileDlg::saveProfile(uint64_t id) {
	Profile p;
	p.setID(id);
	getProfile(p);
	p.save();
	profileid = p.getID();
	loadProfiles();
}

void ProfileDlg::deleteProfile(uint64_t id) {
	if(id) {
		aSQLite sql(app.getHomeDir(),"profile");
		sql.execf("delete from profile where id=%" PRIu64 ";",id);
		loadProfiles();
	}
	clearForm();
}


/*
bool ProfileDlg::command(WPARAM wParam,LPARAM lParam) {
//fprintf(out,"ProfileDlg::command=%d\n",LOWORD(wParam));
//fflush(out);
	switch(LOWORD(wParam)) {
		case IDC_PROFILE_CAT:
			if(HIWORD(wParam)==CBN_SELENDOK) {
				selectProfilesFromCategory(GetDlgItem(getHWND(),IDC_PROFILE_PERSDB),SendMessage((HWND)lParam,CB_GETCURSEL,0,0));
				return true;
			}
			return false;
		case IDC_PROFILE_PERSDB:
			switch(HIWORD(wParam)) {
				case LBN_SELCHANGE:
				{
					int index = SendMessage((HWND)lParam,LB_GETCURSEL,0,0);
					if(index!=LB_ERR) {
						char str[33];
						SendMessage((HWND)lParam,LB_GETTEXT,index,(LPARAM)str);
						Profile *p1 = new Profile(str,cat);
						if(p1->load()) setProfile(*p1);
						delete p1;
					}
					return true;
				}
				case LBN_DBLCLK:SendMessage(getHWND(),WM_COMMAND,(WPARAM)IDOK,lParam);return true;
			}
			return false;
		case IDC_PROFILE_MONTH:
		case IDC_PROFILE_DAY:
		case IDC_PROFILE_HOUR:
		case IDC_PROFILE_MINUTE:
		case IDC_PROFILE_SECOND:
		case IDC_PROFILE_TIMEZONE:
			if(HIWORD(wParam)==CBN_SELENDOK) {
				float gmt;
				char str[32],tz[32];
				HWND hwnd = getHWND();

				GetDlgItemText(hwnd,IDC_PROFILE_TIMEZONE,str,31);
				if(!*str) break;
				gmt = getTimeZone(str,tz);
				GetDlgItemText(hwnd,IDC_PROFILE_YEAR,str,31);
				int year = atoi(str);
				int month = SendMessage(GetDlgItem(hwnd,IDC_PROFILE_MONTH),CB_GETCURSEL,0,0)+1;
				int day = SendMessage(GetDlgItem(hwnd,IDC_PROFILE_DAY),CB_GETCURSEL,0,0)+1;
				int hour = SendMessage(GetDlgItem(hwnd,IDC_PROFILE_HOUR),CB_GETCURSEL,0,0);
				int minute = SendMessage(GetDlgItem(hwnd,IDC_PROFILE_MINUTE),CB_GETCURSEL,0,0);
				int second = SendMessage(GetDlgItem(hwnd,IDC_PROFILE_SECOND),CB_GETCURSEL,0,0);
				return true;
			}
			return false;
		case IDC_PROFILE_COUNTRY:
			if(HIWORD(wParam)==CBN_SELENDOK) {
				char str[64],buf[64];
				HWND hcb = (HWND)lParam;
				int index = SendMessage(hcb,CB_GETCURSEL,0,0);
				SendMessage(hcb,CB_GETLBTEXT,index,(LPARAM)buf);
				getCountryCode(str,buf);
				selectCountry(str);
				return true;
			}
			return false;
		case IDC_PROFILE_LOCATION:
			if(HIWORD(wParam)==CBN_SELENDOK) {
				if(!*country) break;
				char str[64],buf[256];
				HWND hwnd = getHWND();
				HWND hcb = (HWND)lParam;
				int index = SendMessage(hcb,CB_GETCURSEL,0,0);
				SendMessage(hcb,CB_GETLBTEXT,index,(LPARAM)str);
				aResultset rs;
				sprintf(buf,"select l.longitude,l.latitude,tz.gmt,tz.name from location as l "
					"left join timezone as tz on tz.name=l.timezone "
						"where l.country='%s' and l.name='%s';",country,str);
				aSQLite sql("files\\location.sv.dat");
				sql.query(buf,&rs);
				if(!rs.size()) break;
				aRecord *r = (aRecord *)rs[0];
				SetDlgItemText(getHWND(),IDC_PROFILE_LONGITUDE,r->getString(0));
				SetDlgItemText(getHWND(),IDC_PROFILE_LATITUDE,r->getString(1));
				hcb = GetDlgItem(hwnd,IDC_PROFILE_TIMEZONE);
				printTimeZone(str,r->getDouble(2),r->getString(3));
fprintf(out,"ProfileDlg::timezone('%s')\n",str);
fflush(out);
				SendMessage(hcb,CB_SELECTSTRING,(WPARAM)-1,(LPARAM)str);
				return true;
			}
			return false;
		case IDC_PROFILE_SAVE:
			if(HIWORD(wParam)==BN_CLICKED) {
				char str[32],buf[256];
				HWND hwnd = getHWND();
				GetDlgItemText(hwnd,IDC_PROFILE_NAME,str,31);
				Profile *p = new Profile(str);
				p->load();
				getProfile(*p);
				p->save();
				SendMessage(GetDlgItem(hwnd,IDC_PROFILE_CAT),CB_SETCURSEL,0,0);
				sprintf(buf,"Profilen '%s' sparad.",str);
				MessageBox(hwnd,buf,"Profil sparad!",MB_OK);
				delete p;
				return true;
			}
			return false;
		case IDC_PROFILE_CLEAR:
			if(HIWORD(wParam)==BN_CLICKED) {
				clearForm();
				return true;
			}
			return false;
		case IDC_PROFILE_DELETE:
			if(HIWORD(wParam)==BN_CLICKED) {
				char str[32],buf[256];
				HWND hwnd = getHWND();

				GetDlgItemText(hwnd,IDC_PROFILE_NAME,str,31);
				sprintf(buf,"delete from profile where name='%s';",str);
				aSQLite sql("files\\profile.sv.dat");
				sql.query(buf);
				clearForm();
				sprintf(buf,"Profilen '%s' raderad.",str);
				MessageBox(hwnd,buf,"Profil raderad!",MB_OK);
				return true;
			}
			return false;
		case IDOK:
			if(HIWORD(wParam)==BN_CLICKED) {
				char str[32];
				HWND hwnd = getHWND();
				GetDlgItemText(hwnd,IDC_PROFILE_NAME,str,31);
				Profile *p1 = new Profile(str);
				p1->load();
				Profile *p2 = new Profile(str,0,p1->id());
				getProfile(*p2);
				if(true) {
					if(!p2->id() || strcmp(p2->name(),p1->name())) p2->save();
					else if(!p2->equals(*p1)) {
						switch(MessageBox(hwnd,"Vill du spara ändringarna?","Spara ändringar...",MB_YESNOCANCEL)) {
							case IDYES:p2->save();
							case IDNO:break;
							case IDCANCEL:delete p2;p2 = 0;break;
						}
					}
				} else {
					MessageBox(hwnd,"Formuläret är inte korrekt ifyllt!","Fel...",MB_ICONEXCLAMATION|MB_OK);
					delete p2;
					p2 = 0;
				}
				delete p1;
				if(p2) {
					hide();
					if(eventFunction) eventFunction(eventObject,p2);
					else createNatalHoroscope(p2);
					delete p2;
				}
				return true;
			}
			return false;
		case IDCANCEL:
			switch(HIWORD(wParam)) {
				case BN_CLICKED:
					hide();
					return true;
			}
			return false;
	}
	return false;
}
*/

